﻿/**	@file		plane.hpp
 *	@date		(2007-09-15 13:46:55)/(2011-07-09 15:00:49)
 *-----------------------------------------------------------------------------
 *	@version	1.0.1.2
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/


#if			!defined(__LOLIX__SOLA__PLANE__K_IN_G__)
#define		__LOLIX__SOLA__PLANE__K_IN_G__

#if			!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)
	#include	"../lolix_cfg.h"
#endif	//	!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)

#if			!defined(__LOLIX__SOLA__VEC__NICK__K_IN_G__)
	#include	"./vec.hpp"
#endif		//	!defined(__LOLIX__SOLA__VEC__NICK__K_IN_G__)
#if			!defined(__LOLIX__SOLA__TRIANGLE__K_IN_G__)
	#include	"./triangle.hpp"
#endif	//	!defined(__LOLIX__SOLA__TRIANGLE__K_IN_G__)


namespace lolix{namespace sola{
	template<typename _Ty>
	class plane
	{
		typedef	plane<_Ty>	this_type;
	public:
		typedef	_Ty				element_type;
		typedef	vec<3, _Ty>	normal_type;

		LOLIX_INLINE_CALL	plane<_Ty>(void){}
		template<typename _Tn, typename _Td>
		LOLIX_INLINE_CALL	plane<_Ty>(const vec<3, _Tn>& in_n, const _Td& in_d)
			: n(in_n), d(in_d){}
		template<typename	_To>
		LOLIX_INLINE_CALL	plane<_Ty>(const plane<_To>& o)
			: n(o.n), d(o.d){}
		template<typename _Tt>
		LOLIX_INLINE_CALL	plane<_Ty>(const triangle<_Tt>& o)
			{ operator()(o); }

		template<typename _Tt>
		LOLIX_INLINE_CALL	this_type&	operator()(const triangle<_Tt>& o)
			{
			normal_type a(o.v[1]-o.v[0]);
			normal_type	b(o.v[2]-o.v[1]);
			n = a.cross(b);
			d = -o.v[1].dot(n);
			return *this;
			}

		template<typename _Tt, size_type _Dim>	//	投影
		LOLIX_INLINE_CALL vec<_Dim, _Tt> shadow(vec<_Dim, _Tt> const& v)
			{
			return v - n*(v.dot(n) + d);
			}

		normal_type		n;	//	nml
		element_type	d;	//	D = -dot(P, N);
	};
}}

#endif	//	!defined(__LOLIX__SOLA__PLANE__K_IN_G__)

